package com.example.nettyrpcdemo;

import com.example.nettyrpcdemo.core.RpcService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import lombok.extern.slf4j.Slf4j;
import msg.MsgCross;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@Slf4j
@SpringBootTest(classes = ServerApplication.class)
class NettyRpcDemoApplicationTests {

    @Autowired
    private RpcService rpcService;

    @Test
    void send() {
        for (int i = 0; i < 10; i++) {
            MsgCross.TestMessage.Builder builder = MsgCross.TestMessage.newBuilder();
            builder.setTag("send" + i);

            rpcService.send(1, builder.build());
        }

        sleep10();
    }

    @Test
    void syncCall() throws Exception {
        long start = System.currentTimeMillis();
        int num = 100000;
        for (int i = 0; i < num; i++) {
            MsgCross.TestAsk.Builder builder = MsgCross.TestAsk.newBuilder();
            builder.setTag("syncCall" + i);

            MsgCross.TestAnswer answer = rpcService.syncCall(1, builder.build(), MsgCross.TestAnswer.class);
            if (answer == null) {
                log.error("调用失败");
                continue;
            }
            //            log.info("answer tag={}", answer.getTag());
        }
        log.info("once cost={}ms", (System.currentTimeMillis() - start) * 1.0 / num); // once cost=0.22011ms

        sleep10();
    }

    @Test
    void asyncCall() {
        long start = System.currentTimeMillis();
        int num = 100000;
        AtomicInteger count = new AtomicInteger();

        for (int i = 0; i < num; i++) {
            MsgCross.TestAsk.Builder builder = MsgCross.TestAsk.newBuilder();
            builder.setTag("asyncCall" + i);

            rpcService.asyncCall(1, builder.build(), MsgCross.TestAnswer.class, (answer -> {
                if (count.incrementAndGet() >= num) {
                    log.info("once cost={}ms", (System.currentTimeMillis() - start) * 1.0 / num); //  once cost=0.08183ms
                }

                if (answer == null) {
                    log.error("call ret error");
                    return;
                }
                //                log.info("answer tag={}", answer.getTag());
            }));
        }

        sleep10();
    }

    private void sleep10() {
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
